﻿/*
 * User: RSny
 * Date: 5/10/2012
 * Time: 10:10 AM
 */
using System;
using System.Runtime.InteropServices;

namespace Aspects.Custom.Audio
{
    public class WaveNative
    {
		public const int CALLBACK_FUNCTION = 0x00030000;    // dwCallback is a FARPROC 

		public const int TIME_MS = 0x0001;  // time in milliseconds 
		public const int TIME_SAMPLES = 0x0002;  // number of wave samples 
		public const int TIME_BYTES = 0x0004;  // current byte offset 

		// callbacks
		public delegate void WaveDelegate(IntPtr hdrvr, WaveMessage uMsg, int dwUser, ref WaveHeader wavhdr, IntPtr dwParam2);
		// WaveOut calls
		[DllImport("winmm.dll")]
		public static extern int waveOutGetNumDevs();
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHeader lpWaveOutHdr, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHeader lpWaveOutHdr, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutWrite(IntPtr hWaveOut, ref WaveHeader lpWaveOutHdr, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutReset(IntPtr hWaveOut);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutClose(IntPtr hWaveOut);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutPause(IntPtr hWaveOut);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutRestart(IntPtr hWaveOut);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

		// WaveIn calls
		[DllImport("winmm.dll")]
		public static extern int waveInGetNumDevs();
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInAddBuffer(IntPtr hwi, ref WaveHeader pwh, int cbwh);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInClose(IntPtr hwi);
		
		/// <summary>
		/// The waveInOpen function opens the given waveform-audio input device for recording.
		/// </summary>
		/// <param name="phwi">Pointer to a buffer that receives a handle identifying the open waveform-audio input device. Use this handle to identify the device when calling other waveform-audio input functions. This parameter can be NULL if WAVE_FORMAT_QUERY is specified for fdwOpen.</param>
		/// <param name="uDeviceID">Identifier of the waveform-audio input device to open. It can be either a device identifier or a handle of an open waveform-audio input device.</param>
		/// <param name="lpFormat">Pointer to a WAVEFORMATEX structure that identifies the desired format for recording waveform-audio data. You can free this structure immediately after waveInOpen returns. </param>
		/// <param name="dwCallback">Pointer to a fixed callback function, an event handle, a handle to a window, or the identifier of a thread to be called during waveform-audio recording to process messages related to the progress of recording.</param>
		/// <param name="dwInstance">User-instance data passed to the callback mechanism. This parameter is not used with the window callback mechanism. </param>
		/// <param name="dwFlags">Flags for opening the device</param>
		/// <returns>Returns MMSYSERR_NOERROR if successful or an error otherwise. Possible error values include the following. </returns>
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInOpen(out IntPtr phwi, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInPrepareHeader(IntPtr hWaveIn, ref WaveHeader lpWaveInHdr, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHeader lpWaveInHdr, int uSize);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInReset(IntPtr hwi);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInStart(IntPtr hwi);
		[DllImport("winmm.dll")]
		public static extern MMSYSERROR waveInStop(IntPtr hwi);		
    }
}